package org.qiandaosystem.qiandaosystemsource.service;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.qiandaosystem.qiandaosystemsource.common.ApiResponse;
import org.qiandaosystem.qiandaosystemsource.dto.SignActivityDTO;
import org.qiandaosystem.qiandaosystemsource.dto.TeacherDTO;
import org.qiandaosystem.qiandaosystemsource.entity.*;
import org.qiandaosystem.qiandaosystemsource.mapper.*;
import org.qiandaosystem.qiandaosystemsource.util.JwtUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class StudentService {

    private final JwtUtil jwtUtil;
    private final UserMapper userMapper;
    private final StudentMapper studentMapper;
    private final TeacherMapper teacherMapper;
    private final SignActivityMapper signActivityMapper;
    private final SignRecordMapper signRecordMapper;

    public ApiResponse<?> getTeacherSignActivities(String jwt) {
        Student student = validateAndGetStudent(jwt);
        if (student == null) {
            return ApiResponse.error("无效的学生账号");
        }

        if (student.getTeacherId() == null) {
            return ApiResponse.error("学生未加入任何教师班级");
        }

        // 获取教师信息
        Teacher teacher = teacherMapper.findByUserId(student.getTeacherId());
        User teacherUser = userMapper.findById(teacher.getUserId());
        if (teacher == null || teacherUser == null) {
            return ApiResponse.error("教师信息不存在");
        }

        List<SignActivity> activities = signActivityMapper.findByTeacherId(student.getTeacherId());
        List<SignActivityDTO> activityDTOs = activities.stream()
                .map(activity -> SignActivityDTO.fromEntity(activity, teacher, teacherUser))
                .collect(Collectors.toList());
        return ApiResponse.success(activityDTOs);
    }

    @Transactional
    public ApiResponse<?> signActivity(String jwt, Integer activityId) {
        Student student = validateAndGetStudent(jwt);
        if (student == null) {
            return ApiResponse.error("无效的学生账号");
        }

        // 检查签到活动是否存在且属于学生的老师
        SignActivity activity = signActivityMapper.findByIdAndTeacherId(activityId, student.getTeacherId());
        if (activity == null) {
            return ApiResponse.error("签到活动不存在或已被删除");
        }

        // 检查是否在签到时间范围内
        LocalDateTime now = LocalDateTime.now();
        if (now.isBefore(activity.getStartTime()) || now.isAfter(activity.getEndTime())) {
            return ApiResponse.error("不在签到时间范围内");
        }

        // 检查是否已经签到
        if (signRecordMapper.findByActivityIdAndStudentId(activityId, student.getUserId()) != null) {
            return ApiResponse.error("已经签到过了");
        }

        // 创建签到记录
        SignRecord record = new SignRecord();
        record.setActivityId(activityId);
        record.setStudentId(student.getUserId());
        record.setSignTime(now);
        record.setStatus(SignRecord.SignStatus.success);
        record.setDetail("普通签到");
        
        signRecordMapper.insert(record);
        return ApiResponse.success("签到成功", record);
    }

    @Transactional
    public ApiResponse<?> codeSign(String jwt, Integer activityId, String signCode) {
        Student student = validateAndGetStudent(jwt);
        if (student == null) {
            return ApiResponse.error("无效的学生账号");
        }

        // 检查签到活动是否存在且属于学生的老师
        SignActivity activity = signActivityMapper.findByIdAndTeacherId(activityId, student.getTeacherId());
        if (activity == null) {
            return ApiResponse.error("签到活动不存在或已被删除");
        }

        // 检查是否是签到码签到类型
        if (activity.getType() != SignActivity.SignType.code) {
            return ApiResponse.error("该活动不是签到码签到类型");
        }

        // 检查签到码是否正确
        if (!activity.getSecret().equals(signCode)) {
            return ApiResponse.error("签到码错误");
        }

        // 检查是否在签到时间范围内
        LocalDateTime now = LocalDateTime.now();
        if (now.isBefore(activity.getStartTime()) || now.isAfter(activity.getEndTime())) {
            return ApiResponse.error("不在签到时间范围内");
        }

        // 检查是否已经签到
        if (signRecordMapper.findByActivityIdAndStudentId(activityId, student.getUserId()) != null) {
            return ApiResponse.error("已经签到过了");
        }

        // 创建签到记录
        SignRecord record = new SignRecord();
        record.setActivityId(activityId);
        record.setStudentId(student.getUserId());
        record.setSignTime(now);
        record.setStatus(SignRecord.SignStatus.success);
        record.setDetail("签到码签到");
        
        signRecordMapper.insert(record);
        return ApiResponse.success("签到成功", record);
    }

    public ApiResponse<?> getSignRecords(String jwt) {
        Student student = validateAndGetStudent(jwt);
        if (student == null) {
            return ApiResponse.error("无效的学生账号");
        }

        // 获取学生的签到记录，并过滤掉已删除活动的记录
        List<SignRecord> allRecords = signRecordMapper.findByStudentId(student.getUserId());
        List<SignRecord> validRecords = allRecords.stream()
                .filter(record -> {
                    SignActivity activity = signActivityMapper.findByIdAndTeacherId(record.getActivityId(), student.getTeacherId());
                    return activity != null; // 如果活动不存在（已删除），则过滤掉
                })
                .collect(Collectors.toList());
        
        return ApiResponse.success(validRecords);
    }

    public ApiResponse<?> getPendingSignActivities(String jwt) {
        Student student = validateAndGetStudent(jwt);
        if (student == null) {
            return ApiResponse.error("无效的学生账号");
        }

        if (student.getTeacherId() == null) {
            return ApiResponse.error("学生未加入任何教师班级");
        }

        // 获取教师信息
        Teacher teacher = teacherMapper.findByUserId(student.getTeacherId());
        User teacherUser = userMapper.findById(teacher.getUserId());
        if (teacher == null || teacherUser == null) {
            return ApiResponse.error("教师信息不存在");
        }

        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();

        // 获取所有未过期且未删除的签到活动
        List<SignActivity> allActivities = signActivityMapper.findByTeacherId(student.getTeacherId()).stream()
                .filter(activity -> !now.isAfter(activity.getEndTime()))
                .collect(Collectors.toList());

        // 获取学生已签到的活动ID
        List<Integer> signedActivityIds = signRecordMapper.findByStudentId(student.getUserId()).stream()
                .map(SignRecord::getActivityId)
                .collect(Collectors.toList());

        // 过滤出未签到的活动，并转换为DTO
        List<SignActivityDTO> pendingActivities = allActivities.stream()
                .filter(activity -> !signedActivityIds.contains(activity.getId()))
                .map(activity -> SignActivityDTO.fromEntity(activity, teacher, teacherUser))
                .collect(Collectors.toList());

        return ApiResponse.success(pendingActivities);
    }

    public ApiResponse<?> getExpiredUnsignedActivities(String jwt) {
        Student student = validateAndGetStudent(jwt);
        if (student == null) {
            return ApiResponse.error("无效的学生账号");
        }

        if (student.getTeacherId() == null) {
            return ApiResponse.error("学生未加入任何教师班级");
        }

        // 获取教师信息
        Teacher teacher = teacherMapper.findByUserId(student.getTeacherId());
        User teacherUser = userMapper.findById(teacher.getUserId());
        if (teacher == null || teacherUser == null) {
            return ApiResponse.error("教师信息不存在");
        }

        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();

        // 获取所有已过期且未删除的签到活动
        List<SignActivity> allActivities = signActivityMapper.findByTeacherId(student.getTeacherId()).stream()
                .filter(activity -> now.isAfter(activity.getEndTime()))
                .collect(Collectors.toList());

        // 获取学生已签到的活动ID
        List<Integer> signedActivityIds = signRecordMapper.findByStudentId(student.getUserId()).stream()
                .map(SignRecord::getActivityId)
                .collect(Collectors.toList());

        // 过滤出未签到的活动，并转换为DTO
        List<SignActivityDTO> expiredUnsignedActivities = allActivities.stream()
                .filter(activity -> !signedActivityIds.contains(activity.getId()))
                .map(activity -> SignActivityDTO.fromEntity(activity, teacher, teacherUser))
                .collect(Collectors.toList());

        return ApiResponse.success(expiredUnsignedActivities);
    }

    public ApiResponse<?> getMyTeacher(String jwt) {
        Student student = validateAndGetStudent(jwt);
        if (student == null) {
            return ApiResponse.error("无效的学生账号");
        }

        if (student.getTeacherId() == null) {
            return ApiResponse.error("学生未加入任何教师班级");
        }

        Teacher teacher = teacherMapper.findByUserId(student.getTeacherId());
        if (teacher == null) {
            return ApiResponse.error("教师信息不存在");
        }

        User teacherUser = userMapper.findById(teacher.getUserId());
        if (teacherUser == null) {
            return ApiResponse.error("教师用户信息不存在");
        }

        TeacherDTO teacherDTO = TeacherDTO.fromEntity(teacher, teacherUser);
        return ApiResponse.success(teacherDTO);
    }

    private Student validateAndGetStudent(String jwt) {
        String username = jwtUtil.extractUsername(jwt);
        User user = userMapper.findByUsername(username);
        if (user == null || !"student".equals(user.getRole())) {
            return null;
        }
        return studentMapper.findByUserId(user.getId());
    }
    @Transactional
    public ApiResponse<?> gestureSign(
            String jwt,
            Integer activityId,
            String gesturePoint
    ) {
        Student student = validateAndGetStudent(jwt);
        if (student == null) {
            return ApiResponse.error("无效的学生账号");
        }

        // 检查签到活动是否存在且属于学生的老师
        SignActivity activity = signActivityMapper.findByIdAndTeacherId(
                activityId,
                student.getTeacherId()
        );
        if (activity == null) {
            return ApiResponse.error("九宫格签到活动不存在或已被删除");
        }

        // 检查是否是九宫格手势签到类型
        if (activity.getType() != SignActivity.SignType.gesture) {
            return ApiResponse.error("该活动不是九宫格手势签到类型");
        }

        // 检查手势密码是否正确
        if (!activity.getSecret().equals(gesturePoint)) {
            return ApiResponse.error("手势密码错误");
        }

        // 检查是否在签到时间范围内
        LocalDateTime now = LocalDateTime.now();
        if (now.isBefore(activity.getStartTime()) || now.isAfter(activity.getEndTime())) {
            return ApiResponse.error("不在签到时间范围内");
        }

        // 检查是否已经签到
        if (signRecordMapper.findByActivityIdAndStudentId(
                activityId,
                student.getUserId()
        ) != null) {
            return ApiResponse.error("已经签到过了");
        }

        // 创建签到记录
        SignRecord record = new SignRecord();
        record.setActivityId(activityId);
        record.setStudentId(student.getUserId());
        record.setSignTime(now);
        record.setStatus(SignRecord.SignStatus.success);
        record.setDetail("九宫格手势签到");

        signRecordMapper.insert(record);
        return ApiResponse.success("九宫格签到成功", record);
    }
    @Transactional
    public ApiResponse<?> locationSign(
            String jwt,
            Integer activityId,
            Double lat,
            Double lon
    ) {
        // 验证学生身份
        Student student = validateAndGetStudent(jwt);
        if (student == null) {
            return ApiResponse.error("无效的学生账号");
        }

        // 检查签到活动是否存在且属于学生的老师
        SignActivity activity = signActivityMapper.findByIdAndTeacherId(
                activityId,
                student.getTeacherId()
        );
        if (activity == null) {
            return ApiResponse.error("位置签到活动不存在或已被删除");
        }

        // 检查是否是位置签到类型
        if (activity.getType() != SignActivity.SignType.location) {
            return ApiResponse.error("该活动不是位置签到类型");
        }

        // 检查是否在签到时间范围内
        LocalDateTime now = LocalDateTime.now();
        if (now.isBefore(activity.getStartTime()) || now.isAfter(activity.getEndTime())) {
            return ApiResponse.error("不在签到时间范围内");
        }

        // 解析活动的位置信息字符串（格式：经度,纬度,半径）
        String[] locationParts = parseLocationString(activity.getSecret());
        if (locationParts == null || locationParts.length != 3) {
            return ApiResponse.error("位置信息格式错误");
        }

        Double activityLon = Double.parseDouble(locationParts[0]);
        Double activityLat = Double.parseDouble(locationParts[1]);
        Integer radius = Integer.parseInt(locationParts[2]);

        // 检查位置是否在允许范围内
        if (!isWithinLocationRange(lat, lon, activityLat, activityLon, radius)) {
            return ApiResponse.error("位置不在允许范围内");
        }

        // 检查是否已经签到
        if (signRecordMapper.findByActivityIdAndStudentId(
                activityId,
                student.getUserId()
        ) != null) {
            return ApiResponse.error("已经签到过了");
        }

        // 创建签到记录
        SignRecord record = new SignRecord();
        record.setActivityId(activityId);
        record.setStudentId(student.getUserId());
        record.setSignTime(now);
        record.setStatus(SignRecord.SignStatus.success);
        record.setDetail("位置签到");

        signRecordMapper.insert(record);
        return ApiResponse.success("位置签到成功", record);
    }

    private String[] parseLocationString(String locationString) {
        if (locationString == null) {
            return null;
        }
        return locationString.split(",");
    }

    private boolean isWithinLocationRange(
            Double studentLat,
            Double studentLon,
            Double activityLat,
            Double activityLon,
            Integer radius
    ) {
        // 简单实现：计算两点之间的距离（实际项目中可以使用更精确的地理计算库）
        double distance = calculateDistance(
                studentLat,
                studentLon,
                activityLat,
                activityLon
        );
        return distance <= radius;
    }

    private double calculateDistance(
            Double lat1,
            Double lon1,
            Double lat2,
            Double lon2
    ) {
        // Haversine 公式计算两点之间的距离（单位：米）
        final int EARTH_RADIUS = 6371000; // 地球半径（米）
        double dLat = Math.toRadians(lat2 - lat1);
        double dLon = Math.toRadians(lon2 - lon1);
        double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
                Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
                        Math.sin(dLon / 2) * Math.sin(dLon / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        return EARTH_RADIUS * c;
    }


}


